package ru.passivemoney.root;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import ru.passivemoney.common.Credentials;
import ru.passivemoney.common.Utils;
import ru.passivemoney.interface_for_server.Notifier;
import ru.passivemoney.manage.account.InstrumentsHolder;
import ru.passivemoney.strategy.AStrategy;
import ru.passivemoney.strategy.dummy.DummyStrategy;
import ru.passivemoney.strategy.processors.IProcessor;
import ru.passivemoney.strategy.processors.ProcessorDummy;
import ru.passivemoney.subscribers.ASubscriber;
import ru.passivemoney.subscribers.Subscriber;

import com.dukascopy.api.Instrument;
import com.dukascopy.api.Period;
import com.dukascopy.api.system.ClientFactory;
import com.dukascopy.api.system.IClient;

public class Main {
    private static final Logger logger = LoggerFactory.getLogger(Main.class);
    
    public static void main(String[] args) throws Exception {
    	
    	try{
    		MDC.put("ROUTINGKEY", "common");
	    	// 1. Подключаемся клиентом к серверу и подписываемся на оповещение изменений котировок интересующих валютных пар
	    	IClient client = getConnectedClient("DEMO10037usRLaEU", "usRLa");
	    	Set<Instrument> instruments = InstrumentsHolder.getInstruments();
	        subscribeToInstruments(client, instruments);
	        
	        // 2. Создаём процессоры, призванные проводить технический анализ конкретного инструмента на конкретном периоде
	        //IProcessor processor = new ProcessorIAC();
	        IProcessor processor = new ProcessorDummy();
	        
	        // 3. Создаём стратегию для работы на конкретном инструменте. Кол-во периодов, подлежащих анализу может быть различно
	        Map<Period, IProcessor> processors = new HashMap<Period, IProcessor>();
	        processors.put(Period.FIFTEEN_MINS, processor);
	        processors.put(Period.ONE_HOUR, processor);
	        //AStrategy strategy = new WilliamsStrategy(processors);
	        AStrategy strategy = new DummyStrategy(processors);
	        
	        // 4. Создаём объекты подписчиков, которые будут оповещаться объектом класса Notifier об изменениях котировок и открываемых барах.
	        List<ASubscriber> subscribers = new ArrayList<ASubscriber>();
	        for(Instrument instr : instruments){
	    		Subscriber s = new Subscriber(instr, strategy);
	    		subscribers.add(s);
	    	}
	        Notifier notifier = new Notifier(subscribers);
	        
	        // 5. Начинаем работу
	        client.startStrategy(notifier);
    	}finally{
    		MDC.remove("ROUTINGKEY");
    	}
    }
    
    public static IClient getConnectedClient(String login, String password) throws ClassNotFoundException, IllegalAccessException, InstantiationException{
    	logger.info("Getting client...");
    	IClient client = ClientFactory.getDefaultInstance();
    	logger.info("Client got");
        
    	logger.info("Creating listener for reconnecting if connection will be closed...");
    	Credentials credentials = new Credentials(login, password);
        client.setSystemListener(new Listener(client, credentials));
        logger.info("Listener created");

        logger.info("Connecting client...");
        Utils.connectClientInfinity(client, credentials);
        logger.info("Client connected");
        
        return client;
    }
    
    public static void subscribeToInstruments(IClient client, Set<Instrument> instruments){
    	logger.info("Subscribing to instruments [{}]...", Utils.setToString(instruments));
        client.setSubscribedInstruments(instruments);
        logger.info("Subscribed");
    }
    
}
